﻿using System;

namespace Growatt.CreateCCode
{

    /// <summary>
    /// modebus解析类
    /// </summary>
    public static class DuiHelperModbusProtocol
    {

        /// <summary>
        /// 设置数据的几位数
        /// </summary>
        /// <param name="bitLength">BIT长度 :如长度=8</param>
        /// <param name="value">设置值</param>
        /// <param name="originalData">寄存器的值</param>
        /// <param name="BitStart">起始位置:如bit0 = 0</param>
        /// <returns></returns>
        public static ushort SettingData(int bitLength, byte value, ushort originalData, int BitStart)
        {
            string str = "";
            for (int i = 0; i < bitLength; i++)
            {
                str += "1";
            }
            int data = Convert.ToInt16(str, 2);
            var FinalData = (ushort)((originalData & ~(data << BitStart)) | value << BitStart);
            return FinalData;
        }

        /// <summary>
        /// 读取数据某几位的数值
        /// </summary>
        /// <param name="bitLength">BIT占据长度</param>
        /// <param name="BitStart">起始位:如bit0 = 0</param>
        /// <param name="value">寄存器的值</param>
        /// <returns></returns>
        public static ushort ReadValue(int bitLength, ushort BitStart, ushort value)
        {
            string str = "";
            for (int i = 0; i < bitLength; i++)
            {
                str += "1";
            }
            //即裁剪出指定数字部分再转换
            short data = Convert.ToInt16(str, 2);
            var finalVal = Convert.ToUInt16(Convert.ToString((ushort)(value & (ushort)(data << BitStart)), 2).PadLeft(16, '0').Substring(16 - (BitStart + bitLength), bitLength), 2);
            return finalVal;
        }

        /// <summary>
        /// 读取单个寄存器
        /// </summary>
        /// <param name="ratio"></param>
        /// <param name="rcvd"></param>m
        public static string GetSingleRegister(double ratio, ushort data)
        {
            var radiostring = "";
            if (ratio == 10)
                radiostring = "#0.0";
            else if (ratio == 100) radiostring = "#0.00";
            else if (ratio == 1000) radiostring = "#0.000";
            string re = (Convert.ToDouble(data) / ratio).ToString(radiostring);
            if (ratio == 0)
                re = (Convert.ToDouble(data)).ToString();
            return re;
        }

        /// <summary>
        /// 读取单个寄存器
        /// </summary>
        /// <param name="ratio"></param>
        /// <param name="rcvd"></param>m
        public static string GetSingleRegister(double ratio, short data)
        {
            var radiostring = "";
            if (ratio == 10)
                radiostring = "#0.0";
            else if (ratio == 100) radiostring = "#0.00";
            else if (ratio == 1000) radiostring = "#0.000";
            string re = (Convert.ToDouble(data) / ratio).ToString(radiostring);
            if (ratio == 0)
                re = (Convert.ToDouble(data)).ToString();
            return re;
        }

        /// <summary>
        /// 设置一个byte中各个bit的位值
        /// </summary>
        /// <param name="_word">目标，要设置的byte</param>
        /// <param name="value">值，为目标位设置的值</param>
        /// <param name="offset">值在目标中的偏移量</param>
        /// <returns></returns>
        public static byte SetBits(byte _word, byte value, int offset)
        {
            byte mask_1 = (byte)(value << offset);
            byte mask_2 = (byte)(~mask_1 & _word);
            return (byte)(mask_1 | mask_2);
        }

        /// <summary>
        /// 转换为short
        /// </summary>
        /// <param name="a">低字节</param>
        /// <param name="b">高字节</param>
        /// <returns></returns>
        public static short getShort(byte a, byte b)
        {
            //   BitConverter.ToInt16(new byte[] { a, b }, 0);
            return (short)((a & 0xFF) | (b << 8));
        }



        /// <summary>
        /// 两个字节高低位转换
        /// </summary>
        /// <param name="data"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        public static string TwoByteConvertHL(ushort[] data, int count)
        {
            string texbox = "";
            for (int i = 0; i < count; i++)
            {
                //高低字节显示(高字节显示在前面)
                texbox += GetHighByte(data[i], 1) + "-";
                texbox += GetLowByte(data[i], 1) + "-";
            }
            texbox = texbox.TrimEnd('-');
            return texbox;
        }

        /// <summary>
        /// PF计算
        /// </summary>
        /// <param name="iAddr"></param>
        /// <param name="rcvd"></param>
        /// <returns></returns>
        public static string PFValueCalculate(short iAddr, int data)
        {
            string texbox = "";
            if (iAddr == 0x0005)
            {
                texbox = ((Convert.ToDouble(data) - 10000) / 10000).ToString();
            }
            else
            {
                texbox = (Convert.ToDouble(data)).ToString();
            }
            return texbox;
        }



        /// <summary>
        /// 获取单个字节高4位
        /// </summary>
        /// <param name="data"></param>
        /// <param name="num"></param>
        /// <returns></returns>
        public static int Gethigh4Bit(short data, int num)
        {
            //获取高四位() 12-15 或者 4-7
            byte[] lst = BitConverter.GetBytes(data);
            int height;
            height = ((lst[num] & 0xf0) >> 4);
            return height;
        }

   


        /// <summary>
        ///获取单个字节的低4位
        /// </summary>
        /// <returns></returns>
        public static int GetSingleByteBit4(short data, int num)
        {
            byte[] lst = BitConverter.GetBytes(data);
            int low;
            low = ((lst[num] & 0x0f));
            return low;
        }

        /// <summary>
        /// 获取低字节
        /// </summary>
        /// <param name="ratio"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        public static string GetLowByte(int data, double ratio)
        {
            byte[] byResult = BitConverter.GetBytes(data);
            int dataL = (Convert.ToInt32(byResult[0]));
            return (Convert.ToDouble(dataL) / ratio).ToString();
        }

        /// <summary>
        /// 获取高字节
        /// </summary>
        /// <param name="ratio"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        public static string GetHighByte(int data, double ratio)
        {
            //获取高8位
            byte[] byResult = BitConverter.GetBytes(data);
            int dataH = (Convert.ToInt32(byResult[1]));
            return (Convert.ToDouble(dataH) / ratio).ToString();
        }

        /// <summary>
        /// 获取Bit3-Bit12
        /// </summary>
        /// <param name="ratio"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        public static byte Get3_12(short data)
        {
            var byteRe = (byte)((data & 0xff0) >> 4);
            return byteRe;
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="strBinary"></param>
        /// <returns></returns>
        public static string BinaryToHexString(string strBinary)
        {
            // 1：先将二进制转换成十进制
            //2：再将十进制转换成十六进制字符串
            var Toint = Convert.ToInt32(strBinary, 2);
            var stringHex = Convert.ToString(Toint, 16);
            return stringHex;
        }

        public static string HexStringToBinary(string strHex)
        {
            // 1：先将16进制转换成十进制
            //2：再将十进制转换成2进制字符串
            var Toint = Convert.ToInt32(strHex, 16);
            var stringHex = Convert.ToString(Toint, 2);
            return stringHex;
        }

        /// <summary>
        /// 读取两个寄存器,转变32位(读取无符号)
        /// </summary>
        /// <param name="ratio"></param>
        /// <param name="rcvd"></param>
        public static string GetTwoRegisterValue(double ratio, ushort data, ushort data2)
        {
            uint iData;

            iData = (uint)(data * 256 * 256 + data2);

            string re = (Convert.ToDouble(iData) / ratio).ToString();
            if (ratio == 0)
                re = (Convert.ToDouble(iData)).ToString();
            return re;
        }

        /// <summary>
        ///  short转换为int
        /// </summary>
        /// <param name="firstHalf"></param>
        /// <param name="secondHalf"></param>
        /// <returns></returns>

        public static int TwoShortToInt(short firstHalf, short secondHalf)
        {
            byte[] recbytes = new byte[4];
            recbytes[0] = BitConverter.GetBytes(firstHalf)[0];
            recbytes[1] = BitConverter.GetBytes(firstHalf)[1];
            recbytes[2] = BitConverter.GetBytes(secondHalf)[0];
            recbytes[3] = BitConverter.GetBytes(secondHalf)[1];
            int reconstituted = BitConverter.ToInt32(recbytes, 0);
            return reconstituted;
        }

        /// <summary>
        /// ushort转换为int
        /// </summary>
        /// <param name="firstHalf"></param>
        /// <param name="secondHalf"></param>
        /// <returns></returns>
        public static int TwoShortToInt(ushort firstHalf, ushort secondHalf)
        {
            byte[] recbytes = new byte[4];
            recbytes[0] = BitConverter.GetBytes(firstHalf)[0];
            recbytes[1] = BitConverter.GetBytes(firstHalf)[1];
            recbytes[2] = BitConverter.GetBytes(secondHalf)[0];
            recbytes[3] = BitConverter.GetBytes(secondHalf)[1];
            int reconstituted = BitConverter.ToInt32(recbytes, 0);
            return reconstituted;
        }

        /// <summary>
        /// ushort转换为uint
        /// </summary>
        /// <param name="firstHalf"></param>
        /// <param name="secondHalf"></param>
        /// <returns></returns>
        public static uint TwoShortToUInt(ushort firstHalf, ushort secondHalf)
        {
            byte[] recbytes = new byte[4];
            recbytes[0] = BitConverter.GetBytes(firstHalf)[0];
            recbytes[1] = BitConverter.GetBytes(firstHalf)[1];
            recbytes[2] = BitConverter.GetBytes(secondHalf)[0];
            recbytes[3] = BitConverter.GetBytes(secondHalf)[1];
            uint reconstituted = BitConverter.ToUInt32(recbytes, 0);
            return reconstituted;
        }

        /// <summary>
        /// short转换为uint
        /// </summary>
        /// <param name="firstHalf"></param>
        /// <param name="secondHalf"></param>
        /// <returns></returns>
        public static uint TwoShortToUInt(short firstHalf, short secondHalf)
        {
            byte[] recbytes = new byte[4];
            recbytes[0] = BitConverter.GetBytes(firstHalf)[0];
            recbytes[1] = BitConverter.GetBytes(firstHalf)[1];
            recbytes[2] = BitConverter.GetBytes(secondHalf)[0];
            recbytes[3] = BitConverter.GetBytes(secondHalf)[1];
            uint reconstituted = BitConverter.ToUInt32(recbytes, 0);
            return reconstituted;
        }

        public static (short, short) intToShort(int original)
        {
            byte[] bytes = BitConverter.GetBytes(original);
            short lowValue = BitConverter.ToInt16(bytes, 0);
            short HighValue = BitConverter.ToInt16(bytes, 2);
            return (lowValue, HighValue);
        }

        public static (ushort, ushort) UintToUShort(uint original)
        {
            byte[] bytes = BitConverter.GetBytes(original);
            ushort lowValue = BitConverter.ToUInt16(bytes, 0);
            ushort HighValue = BitConverter.ToUInt16(bytes, 2);
            return (lowValue, HighValue);
        }

        public static (ushort, ushort) intToUShort(int original)
        {
            byte[] bytes = BitConverter.GetBytes(original);
            ushort lowValue = BitConverter.ToUInt16(bytes, 0);
            ushort HighValue = BitConverter.ToUInt16(bytes, 2);
            return (lowValue, HighValue);
        }

        /// <summary>
        /// ushort转换为uint
        /// </summary>
        /// <param name="firstHalf"></param>
        /// <param name="secondHalf"></param>
        /// <returns></returns>
        public static int TwoUShortToInt(ushort firstHalf, ushort secondHalf)
        {
            byte[] recbytes = new byte[4];
            recbytes[0] = BitConverter.GetBytes(firstHalf)[0];
            recbytes[1] = BitConverter.GetBytes(firstHalf)[1];
            recbytes[2] = BitConverter.GetBytes(secondHalf)[0];
            recbytes[3] = BitConverter.GetBytes(secondHalf)[1];
            int reconstituted = BitConverter.ToInt32(recbytes, 0);
            return reconstituted;
        }

        /// <summary>
        /// short转换为ushort
        /// </summary>
        /// <param name="firstHalf"></param>
        /// <param name="secondHalf"></param>
        /// <returns></returns>
        public static ushort ShortToUShort(short Value)
        {
            byte[] recbytes = new byte[2];
            recbytes[0] = BitConverter.GetBytes(Value)[0];
            recbytes[1] = BitConverter.GetBytes(Value)[1];
            ushort reconstituted = BitConverter.ToUInt16(recbytes, 0);
            return reconstituted;
        }

        /// <summary>
        /// ushort转换为short
        /// </summary>
        /// <param name="firstHalf"></param>
        /// <param name="secondHalf"></param>
        /// <returns></returns>
        public static short UShortToShort(ushort Value)
        {
            byte[] recbytes = new byte[2];
            recbytes[0] = BitConverter.GetBytes(Value)[0];
            recbytes[1] = BitConverter.GetBytes(Value)[1];
            short reconstituted = BitConverter.ToInt16(recbytes, 0);
            return reconstituted;
        }

        /// <summary>
        /// 读取两个寄存器,转变32位(有符号)
        /// </summary>
        /// <param name="ratio"></param>
        /// <param name="rcvd"></param>
        public static string GetTwoRegisterValueSigned(double ratio, ushort data, ushort data2)
        {
            int iData;

            iData = (int)(data * 256 * 256 + data2);

            string re = (Convert.ToDouble(iData) / ratio).ToString();
            if (ratio == 0)
                re = (Convert.ToDouble(iData)).ToString();
            return re;
        }

        /// <summary>
        /// 读取两个寄存器,转变16位(有符号)
        /// </summary>
        /// <param name="ratio"></param>
        /// <param name="rcvd"></param>
        public static string GetTwoRegister16Value(double ratio, ushort data, ushort data2)
        {
            int iData;

            iData = (short)(data * 256 * 256 + data2);

            string re = (Convert.ToDouble(iData) / ratio).ToString();
            if (ratio == 0)
                re = (Convert.ToDouble(iData)).ToString();
            return re;
        }

        /// <summary>
        /// 读取两个寄存器,转变16位(无符号)
        /// </summary>
        /// <param name="ratio"></param>
        /// <param name="rcvd"></param>
        public static string GetTwoRegisterU16Value(double ratio, ushort data, ushort data2)
        {
            int iData;

            iData = (ushort)(data * 256 * 256 + data2);

            string re = (Convert.ToDouble(iData) / ratio).ToString();
            if (ratio == 0)
                re = (Convert.ToDouble(iData)).ToString();
            return re;
        }

        /// <summary>
        /// 读获取单个Bit
        /// </summary>
        /// <param name="iBit"></param>
        /// <param name="rcvd"></param>
        /// <returns></returns>
        public static string GetSingleBit(int iBit, int data)
        {
            int iEnable = ((data >> iBit) & 0x0001);
            string texbox = iEnable.ToString();
            return texbox;
        }

        /// <summary>
        /// 16位转换高8位
        /// </summary>
        /// <param name="ratio"></param>
        /// <param name="rcvd"></param>
        public static string IntToHighBit8(double ratio, int data)
        {
            //获取高8位
            byte[] byResult = BitConverter.GetBytes(data);
            int dataH = (Convert.ToInt32(byResult[1]));
            return (Convert.ToDouble(dataH) / ratio).ToString();
        }

        /// <summary>
        /// 16位转换低8位
        /// </summary>
        /// <param name="ratio"></param>
        /// <param name="rcvd"></param>
        public static string IntToLowBit8(double ratio, int data)
        {
            //获取低8位
            byte[] byResult = BitConverter.GetBytes(data);
            int dataL = (Convert.ToInt32(byResult[0]));
            return (Convert.ToDouble(dataL) / ratio).ToString();
        }

        /// <summary>
        /// 16位int转换单个Bit
        /// </summary>
        /// <param name="iBit"></param>
        /// <param name="rcvd"></param>
        /// <returns></returns>
        public static void IntToSingleBit(out string texbox, int iBit, int data)
        {
            int iEnable = ((data >> iBit) & 0x0001);
            texbox = iEnable.ToString();
        }

        /// <summary>
        /// 32int转换16位int
        /// </summary>
        /// <param name="ratio">倍率</param>
        /// <param name="data"><原始数据/param>
        /// <param name="multipliction">是否是乘法运算</param>
        /// <returns></returns>
        public static void IntTo16Int(out string re, double ratio, int data, bool multipliction = false)
        {
            if (!multipliction)
            {
                //都保留一位小数
                re = (Convert.ToDouble(data) / ratio).ToString();
                if (ratio == 0)
                    re = (Convert.ToDouble(data)).ToString();
            }
            else
            {
                re = (Convert.ToDouble(data) * ratio).ToString();
                if (ratio == 0)
                    re = (Convert.ToDouble(data)).ToString("#0");
            }
        }


    }
}